package com.ecarx.vhaltests.hy11.testcases.climate;

import android.car.VehicleAreaSeat;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;
import com.ecarx.xui.adaptapi.car.hvac.IHvac;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import androidx.test.platform.app.InstrumentationRegistry;


@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacFuncAutoDeodorizeSwitchTest extends VhalUnitTestBase {
    private static final String TAG = "HvacFuncAutoDeodorizeSwitchTest";

    final static Object lock = new Object();
    static IpcpClient ipcpClient = new IpcpClient();
    private static IWrapper.IPropertyId autoDeodorizeSwitchPropertyId;
    static IWrapper wrapper;

     private static boolean halValue;
     private static int halStatus;

     private static int halArea;

    private static final int HVAC_FUNC_AREA = VehicleAreaSeat.SEAT_ROW_1_LEFT | VehicleAreaSeat.SEAT_ROW_1_RIGHT | VehicleAreaSeat.SEAT_ROW_2_LEFT
            | VehicleAreaSeat.SEAT_ROW_2_CENTER | VehicleAreaSeat.SEAT_ROW_2_RIGHT;

    @BeforeClass
    public static void testInit() {
        wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        autoDeodorizeSwitchPropertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IHvac.HVAC_FUNC_AUTO_DEODORIZE_SWITCH);
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, autoDeodorizeSwitchPropertyId.getPropertyId(), CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig();
    }

    @Test
    public void test01_HvacFuncAutoDeodorizeSwitchAvail() {
        prepareHvacFuncAutoDeodorizeSwitchTestEnv(true);
        delay();
        testHvacFuncAutoDeodorizeSwitchAvail(true);

    }

    @Test
    public void test02_HvacFuncAutoDeodorizeSwitchNotAvail() {
        prepareHvacFuncAutoDeodorizeSwitchTestEnv(false);
        delay();
        testHvacFuncAutoDeodorizeSwitchAvail(false);
    }


    @Test
    public void test03_HvacFuncAutoDeodorizeSwitchOn() {
        prepareHvacFuncAutoDeodorizeSwitchTestEnv(true);
        delay();
        hvacFuncAutoDeodorizeSwitchSet(true);
    }

    @Test
    public void test04_HvacFuncAutoDeodorizeSwitchOff() {
        prepareHvacFuncAutoDeodorizeSwitchTestEnv(true);
        delay();
        hvacFuncAutoDeodorizeSwitchSet(false);
    }


    private static  CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                halValue = (boolean) carPropertyValue.getValue();
                halStatus = carPropertyValue.getStatus();
                halArea = carPropertyValue.getAreaId();
                Log.d(TAG, "HVAC_FUNC_AUTO_DEODORIZE_SWITCH onChangeEvent value: propertyId ：" + carPropertyValue.getPropertyId() + " propertyValue：" + carPropertyValue.getValue() + " status : " + carPropertyValue.getStatus());
                synchronized (lock) {
                    lock.notify();
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {
        }
    };


    public void lockWait() {
        try {
            synchronized (lock) {
                lock.wait(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    private void testHvacFuncAutoDeodorizeSwitchAvail(boolean except) {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(autoDeodorizeSwitchPropertyId.getPropertyId(), HVAC_FUNC_AREA);
        Log.d(TAG, "testHvacFuncAutoDeodorizeSwitchAvail  isAvail：" + isAvail + " except： " + except);
        Assert.assertEquals(except, isAvail);
    }

    private void hvacFuncAutoDeodorizeSwitchSet(boolean value) {
        boolean bRet = false;
        Log.d(TAG, "HvacFuncAutoDeodorizeSwitchSet set value ：" + value);
        mCarPropertyMgr.setBooleanProperty(autoDeodorizeSwitchPropertyId.getPropertyId(), HVAC_FUNC_AREA, value);
        lockWait();
        Assert.assertEquals(value, halValue);
    }

    private void prepareHvacFuncAutoDeodorizeSwitchTestEnv(boolean avail) {
        setClimateMaxDefrost();
        if (avail) {
            setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_DRIVING);
        } else {
            setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_ABANDON);
        }
    }


    public void setCEM(int carMode, int usgMode) {
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts"};
        int[] cemValues = {carMode, usgMode};
        boolean cemResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(cemResult);
        delay();
    }

    public void setClimateMaxDefrost() {

        String availability_MaxDefrost = "paclmaxdefrost.availability";
        String data_MaxDefrost = "paclmaxdefrost.data";
        String availability_power_front = "paclairctrloff.availability";
        String data_power_front = "paclairctrloff.data";

        String[] config_indexs = {availability_MaxDefrost, data_MaxDefrost, availability_power_front, data_power_front};
        int[] values = {1, 0, 1, 1};
        ipcpClient.setClimaSignal(112, 0xc8, config_indexs, values);
    }


    private static void setConfig() {
        // HY11 car mode & usage mode 信号对应 ECU 为 CEM
        int cemSvcId = 37;
        int[] cemOperIds = {999};
        // carconfig 对应 Service ID & Operation ID
        int ccSvcId = 135;
        int[] ccOperIds = {200};

        int climateSvcId = 112;
        int[] climateOperIds = {0xc8};

        boolean retCem = ipcpClient.setConfig(cemSvcId, cemOperIds);
        Assert.assertTrue(retCem);

        boolean retCc = ipcpClient.setConfig(ccSvcId, ccOperIds);
        Assert.assertTrue(retCc);

        boolean retCdm = ipcpClient.setConfig(climateSvcId, climateOperIds);
        Assert.assertTrue(retCdm);

    }


}
